﻿package dut.ir.lxb.weibo.spider;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Set;

import dut.ir.lxb.weibo.bean.UserBean;
import dut.ir.lxb.weibo.bean.UserWeiboAction;
import dut.ir.lxb.weibo.bean.WeiboBean;
import dut.ir.lxb.weibo.db.UserInfoDao;
import dut.ir.lxb.weibo.db.UserWeiboActionDao;
import dut.ir.lxb.weibo.db.WeiboInfoDao;
import dut.ir.lxb.weibo.util.ActionType;
import dut.ir.lxb.weibo.util.DataExtractor;
import dut.ir.lxb.weibo.util.RelationType;
import dut.ir.lxb.weibo.util.SpiderConfig;

public class DownloadThread implements Runnable
{
	
	protected Queue<WeiboDownloader> downloaderList; 
	
	protected Queue<String> downloadQueue;
	
	protected Set<String> downloadedUids;
	
	/**
	 * 下载开始时间
	 */
	@SuppressWarnings("unused")
	private static Date startTime;
	
	static
	{
		startTime = new Date();
	}
	
	public static Queue<WeiboDownloader> loadWeiboDownloaderList()
	{
		Queue<WeiboDownloader> wdList = new LinkedList<WeiboDownloader>();
		
		try
		{
			BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(SpiderConfig.rootDirectory + "/config/accounts.txt"), "UTF-8"));
			String currentLine = br.readLine();
			while(currentLine != null)
			{
				if(currentLine.trim().length() == 0)
				{
					currentLine = br.readLine();
					continue;
				}
				String username = currentLine.split("\t")[0];
				String password = currentLine.split("\t")[1];
				WeiboDownloader wd = new WeiboDownloader(username, password);
				wdList.add(wd);
				
				currentLine = br.readLine();
			}
			br.close();
		}
		catch (FileNotFoundException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
		
		
		return wdList;
	}
	
	public DownloadThread()
	{
		downloaderList = loadWeiboDownloaderList();
		String rootuid = SpiderConfig.getRootUid();
		downloadQueue = new LinkedList<String>();
		downloadQueue.add(rootuid);
		downloadedUids = new HashSet<String>();
	}
	
	public DownloadThread(String rootUid)
	{
		this();
		downloadQueue.clear();
		downloadQueue.add(rootUid);
	}
	
	public DownloadThread(Queue<WeiboDownloader> dlist)
	{
		this();
		downloaderList = dlist;
	}
	
	
	

	@SuppressWarnings("unused")
	@Override
	public void run()
	{
		Date runTime = new Date();
		int size = 0;
		synchronized(downloadQueue)
		{
			size = downloadQueue.size();
		}
		int downloadTime = 0;
		int maxdownload = 1;

		WeiboDownloader wd = null;
		while(true)
		{
			String uid = "";
			try
			{
				
				synchronized(downloadQueue)
				{
					uid = downloadQueue.poll();
					size = downloadQueue.size();
				}
				
				//如果此ID已经下载过，跳过之
				synchronized(downloadedUids)
				{
					if(downloadedUids.contains(uid) || uid == null || uid.equals(""))
						continue;
				}
				
				//取出一个下载器并登录
				if(wd == null)
				{
					synchronized(downloaderList)
					{
						wd = downloaderList.poll();
						wd.init();
						if(!wd.isLogin)
						{
							downloadQueue.add(uid);
							downloaderList.add(wd);
							wd = null;
							continue;
						}
					}
				}
				
				
				//下载个人信息
				UserBean ub = wd.downloadUserInfo(uid);
				//如果此用户为空可能是未登录成功造成的，取出一个新的下载器
				if(ub == null || ub.getUid() == null || ub.getUid().length() == 0)
				{
					downloadQueue.add(uid);
					if(wd.isLogin)
						wd.finalise();
					downloaderList.add(wd);
					wd = null;
					continue;
				}
				//如果没有认证返回空
				//if(false && !ub.isApproved())
				//	continue;
				System.out.println(Thread.currentThread().getName() + " is downloading user " + ub.getNickName());
				
				
				//将个人信息保存至数据库中
				UserInfoDao ud = UserInfoDao.getInstance();
				ud.insertUser(ub);
				//下载用户的关注
				List<String> newUids = null;
				if(newUids == null)
					newUids = new ArrayList<String>();
				newUids = wd.downloadUserFollowList(ub, RelationType.FOLLOW);
				
				List<WeiboBean> wbList = wd.downloadAUserWeibo(ub);
				downloadTime = (downloadTime + 1) % maxdownload;
				if(wbList == null)
				{
					wbList = new ArrayList<WeiboBean>();
				}
				
				
				String weibofile = String.format(SpiderConfig.getWeiboDirectory() + "%s_weibo.xml", uid);
				//WeiboWriter wbWriter = new WeiboInfoWriter(weibofile);
				
				//将个人微博写入数据库和文件中
				for(WeiboBean currentWeibo : wbList)
				{
					/***************处理此条微博*******************/
					//将此条微博写入数据库和文件中
					WeiboInfoDao wbInfoDao = WeiboInfoDao.getInstance();
					wbInfoDao.insertWeibo(currentWeibo);
					//wbWriter.writeBody(currentWeibo.toXMLText());
					
					UserWeiboActionDao uwd = UserWeiboActionDao.getInstance();
					List<String> actionUids = new ArrayList<String>();
					//若需要点赞信息则下载点赞
					if(SpiderConfig.isLikeNeeded())
					{
						List<UserWeiboAction> likeList = wd.downloadUserWeiboAction(currentWeibo, ActionType.LIKE);
						//把点赞信息写入数据库中
						uwd.insertActionList(likeList);
						//判断是否把点赞用户加入下载队列
						if(SpiderConfig.isLikeUserNeeded())
						{
							actionUids.addAll(DataExtractor.getUidListFromAction(likeList));
						}
					}
					//下载评论信息
					if(SpiderConfig.isCommentNeeded())
					{
						List<UserWeiboAction> commentList = wd.downloadUserWeiboAction(currentWeibo, ActionType.COMMENT);
						//把评论信息写入数据库和文件
						uwd.insertActionList(commentList);
						//判断是否把评论用户加入下载队列
						if(SpiderConfig.isCommentUserNeeded())
						{
							actionUids.addAll(DataExtractor.getUidListFromAction(commentList));
						}
					}
					//下载转发信息
					if(SpiderConfig.isForwardNeeded())
					{
						List<UserWeiboAction> forwardList = wd.downloadUserWeiboAction(currentWeibo, ActionType.FORWARD);
						//把转发信息写入数据库和文件
						uwd.insertActionList(forwardList);
						//判断是否把转发用户加入下载队列
						if(SpiderConfig.isForwardUserNeeded())
						{
							actionUids.addAll(DataExtractor.getUidListFromAction(forwardList));
						}
					}
					for(String actUid : actionUids)
					{
						ub = wd.downloadUserInfo(actUid);
						ud.insertUser(ub);
					}
					try
					{
						Thread.currentThread();
						Thread.sleep(1000);
					} catch (InterruptedException e)
					{
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				//关闭微博写入流
				//wbWriter.close();
				
				//Uid过滤
				List<String> filterUids = new ArrayList<String>();
				synchronized(downloadedUids)
				{
					downloadedUids.add(uid);
					for(String currentUid : newUids)
					{
						if(!downloadedUids.contains(currentUid))
							filterUids.add(currentUid);
					}
				}
				
				//将新UID加入下载队列
				synchronized(downloadQueue)
				{
					for(String currentUid : filterUids)
					{
						if(!downloadQueue.contains(currentUid))
							downloadQueue.add(currentUid);
					}
				}
				
				//将当前下载器重新加入下载器列表
				synchronized(downloaderList)
				{
					if(wd != null)
						if(wd.isLogin)
							wd.finalise();
					downloaderList.add(wd);
					wd = null;
				}
			
			}
			catch(Exception e)
			{
				e.printStackTrace();
				downloadQueue.add(uid);
				if(wd.isLogin)
					wd.finalise();
				downloaderList.add(wd);
				wd = null;
				continue;
			}
			
			
		}
		
	}
	
}
